#include "mainwindow.h"
#include "myQgsMapCanvas.h"

#include "ui_mainwindow.h"
#include "LayerCheckBoxDelegate.h"
#include <QFileDialog>
#include <QMessageBox>
#include <QStatusBar>
#include <QPushButton>

// 引入QGIS相关的头文件
#include <qgis.h>
#include <qgsapplication.h>
#include <qgis_core.h>
#include <qgsapplication.h>
#include <qgsmapcanvas.h>
#include <qgsvectorlayer.h>
#include <qgsproject.h>
#include <qgsmaptoolpan.h>
#include <qgspointxy.h>
#include <qgscoordinatereferencesystem.h>
#include <qgscoordinatetransform.h>
#include <qgsrasterlayer.h>  // 包含 QgsRasterLayer 类
#include <qgslayertree.h>       // 用于层树节点管理
#include <qgslayertreenode.h>   // 用于单个图层节点
#include <qgsfield.h>
#include <qgspoint.h>
#include <qgsfeature.h>
#include <qgsgeometry.h>
#include <qgslinestring.h>   // 用于 QgsLineString


#include <QDebug>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    // 初始化QGIS应用程序
    QgsApplication::setPrefixPath("/usr", true); // 设置QGIS安装路径
    QgsApplication::init(); // 初始化QGIS应用

    ui->openButton->hide();
    ui->AddMifButton->hide();

    // 创建地图画布
    canvas = new MyQgsMapCanvas();
    //canvas->setCanvasColor(Qt::white);
    canvas->setCanvasColor(Qt::black);
    ui->horizontalLayout02->addWidget(canvas); // 在UI中加入canvas

    // 添加默认图层
    QgsProject::instance()->clear();

    // 设置画布的属性
    // 确保画布设置了正确的地图比例尺和坐标系
    QgsCoordinateReferenceSystem crs("EPSG:4326");  // 例如，使用 WGS 84 坐标系

    canvas->setDestinationCrs(crs);  // 设置坐标系
    canvas->enableAntiAliasing(true);  // 启用抗锯齿
    canvas->setParallelRenderingEnabled(true);
    // 使用 mapSettings 获取画布设置
    QgsMapSettings mapSettings = canvas->mapSettings();
    mapSettings.setDestinationCrs(crs);
    //canvas->setCrsTransformEnabled(true);

    canvas->setExtent(QgsRectangle(-180, -90, 180, 90)); // 设置显示范围
    canvas->setAttribute(Qt::WA_Hover, true);
    //canvas->setAttribute(Qt::WA_TransparentForMouseEvents, true); //
    canvas->installEventFilter(this);
    //setAttribute(Qt::WA_OpaquePaintEvent, true);
    //this->installEventFilter(this);

    //setCentralWidget(canvas);

    //QString qgisVersion = QgsApplication::showSettings();
    QString qgisVersion = Qgis::version();
    qDebug() << "QGIS Version:" << qgisVersion;



    //QgsCoordinateTransform coordTransform(crs, mapSettings.destinationCrs(), QgsProject::instance());
}
MainWindow::~MainWindow()
{
    delete ui;
    QgsApplication::exitQgis(); // 清理QGIS应用资源
}

// 平移地图
void MainWindow::on_panButton_clicked()
{
    // 启用平移模式
    canvas->setMapTool(new QgsMapToolPan(canvas));

}


// 打开Shapefile文件
//void on_pushButton_clicked();
//void onMouseMoved(const QgsPointXY &point); // 鼠标移动时更新经纬度
void MainWindow::on_openButton_clicked()
{
    QString fileName = QFileDialog::getOpenFileName(this, tr("打开Shapefile"), "", tr("Shapefiles (*.shp);;所有文件 (*.*)"));
    if (fileName.isEmpty()) {
        return;
    }

    // 加载Shapefile
    QgsVectorLayer *layer = new QgsVectorLayer(fileName, "Shapefile Layer", "ogr");

    if (!layer->isValid()) {
        QMessageBox::warning(this, tr("加载失败"), tr("无法加载Shapefile文件"));
        delete layer;
        return;
    }

    // 将图层添加到QGIS项目中
    QgsProject::instance()->addMapLayer(layer);

    // 将图层显示在地图画布上
    canvas->setLayers({layer});

    // 设置视图范围以适应新加载的图层
    canvas->zoomToFullExtent();
}

// 缩放地图
void MainWindow::on_ZoomInButton_clicked()
{
    canvas->zoomIn();
    statusBar()->showMessage("on_ZoomInButton_clicked!");
}

void MainWindow::on_ZoomOutButton_clicked()
{
    canvas->zoomOut();
}

QString MainWindow::degreesToDMS(double degrees) {
    int d = static_cast<int>(degrees); // 度
    int minutes = static_cast<int>((degrees - d) * 60.0); // 分
    int seconds = static_cast<int>(((degrees - d) * 60.0 - minutes) * 60.0); // 秒

    return QString("%1° %2' %3\"").arg(d).arg(minutes, 2, 10, QChar('0')).arg(seconds, 2, 10, QChar('0'));
}
// 重写 event() 函数来捕获 hoverMoveEvent
bool MainWindow::eventFilter(QObject *watched, QEvent *event) {
    if (watched == canvas && event->type() == QEvent::HoverMove) {
        QHoverEvent *hoverEvent = static_cast<QHoverEvent *>(event);
        QPoint mousePos = hoverEvent->pos();
        //QPointF screenPosF(mousePos);  // 将 QPoint 转换为 QPointF
        // 将屏幕坐标转换为 QgsPointXY
        QgsPointXY screenPoint(mousePos.x(), mousePos.y());

        //qDebug() << "Mouse moved to:" << mousePos;
        QString tmpstr=QString("(%1,%2)").arg(screenPoint.x()).arg(screenPoint.y());

        // 使用 mapSettings 获取画布设置
        //QgsMapSettings mapSettings = canvas->mapSettings();
        //double myscal=mapSettings.scale();
        qreal myscal=canvas->scale();

        // 获取当前图层，假设我们只使用第一个图层
        //QgsMapLayer *layer = canvas->currentLayer();  // 或者您可以手动选择图层
        // int cnt=canvas->layerCount();
        // QgsMapLayer *layer = canvas->layer(cnt-1);  // 或者您可以手动选择图层
        // if (layer == nullptr) {
        //     qDebug() << "No current layer available.";
        //     return false;
        // }

        // 使用 layerToMapCoordinates 将屏幕坐标转换为地图坐标
        //QgsPointXY mapCoordinates = mapSettings.layerToMapCoordinates(layer, screenPoint);
        //QgsPointXY mapCoordinates = mapSettings.mapToLayerCoordinates(layer, screenPoint);
        //QgsPointXY mapCoordinates = canvas->mapToLayerCoordinates(layer, screenPoint);
        //QPoint mapCoordinates = canvas->mapFromScene(mousePos);
        // 获取坐标转换对象


        // 将屏幕坐标转换为地图坐标（根据设置的目标坐标参考系统）
        QgsPointXY mapCoordinates =canvas->getCoordinateTransform()->toMapCoordinates(mousePos);

        QString jdstr=degreesToDMS(mapCoordinates.x());
        QString wdstr=degreesToDMS(mapCoordinates.y());
        // 将屏幕坐标转换为地图坐标
        //QgsPointXY mapCoordinates = mapSettings.layerToMapCoordinates(canvas->layer(0), mousePos);

        // 将屏幕坐标转换为地图坐标
        //QgsPointXY mapCoordinates = canvas->getCoordinateFromScreen(mousePos);

        //tmpstr+=QString("(%1,%2)").arg(mapCoordinates.x()).arg(mapCoordinates.y());
        tmpstr+="("+jdstr+","+wdstr+")";
        tmpstr+=QString(",1:%1").arg(myscal/1000,0,'f',0);
        statusBar()->showMessage(tmpstr);
        return true; // 事件已处理
    }

    return QMainWindow::eventFilter(watched, event);
}

// void MainWindow::mousePressEvent(QMouseEvent *event)
// {
//     // 检测鼠标中键按下
//     if (event->button() == Qt::MiddleButton)
//     {
//         qDebug()<<"MiddleButton!";
//     }
// }
// QgsPointXY MainWindow::getCoordinateFromScreen(const QPoint &screenPos) {
//     //return canvas->toMapCoordinates(screenPos);
//     return canvas->xyCoordinates(screenPos);
// }



void MainWindow::on_AddShpButton_clicked()
{
    // 弹出文件对话框，选择要加载的另一个 Shapefile 文件
    QString fileName = QFileDialog::getOpenFileName(this, tr("打开另一个 Shapefile"), "", tr("Shapefiles (*.shp);;所有文件 (*.*)"));
    if (fileName.isEmpty()) {
        return;
    }

    // 加载 Shapefile 文件
    QgsVectorLayer *newLayer = new QgsVectorLayer(fileName, "Another Shapefile Layer", "ogr");

    if (!newLayer->isValid()) {
        QMessageBox::warning(this, tr("加载失败"), tr("无法加载 Shapefile 文件"));
        delete newLayer;
        return;
    }

    // 将新图层添加到 QGIS 项目中
    QgsProject::instance()->addMapLayer(newLayer);

    // 获取现有图层，并将其与新图层一起显示在地图画布上
    QList<QgsMapLayer *> layers = QgsProject::instance()->mapLayers().values();

    // 将现有图层和新图层叠加显示
    canvas->setLayers(layers);

    // 设置视图范围以适应所有图层
    canvas->zoomToFullExtent();
}


void MainWindow::on_AddMifButton_clicked()
{
    QString fileName = QFileDialog::getOpenFileName(this, tr("打开MIF文件"), "", tr("MapInfo MIF Files (*.mif);;所有文件 (*.*)"));
    if (fileName.isEmpty()) {
        return;
    }

    // 生成相应的MID文件名
    QFileInfo fileInfo(fileName);
    QString midFileName = fileInfo.path() + "/" + fileInfo.baseName() + ".mid";

    // 检查MID文件是否存在
    if (!QFile::exists(midFileName)) {
        QMessageBox::warning(this, tr("文件丢失"), tr("无法找到相关的MID文件"));
        return;
    }

    // 加载MIF文件
    QgsVectorLayer *layer = new QgsVectorLayer(fileName, "MIF Layer", "mapinfo");

    if (!layer->isValid()) {
        QMessageBox::warning(this, tr("加载失败"), tr("无法加载MIF文件"));
        delete layer;
        return;
    }

    // 将图层添加到QGIS项目中
    QgsProject::instance()->addMapLayer(layer);
    project = QgsProject::instance();

    // 将图层显示在地图画布上
    canvas->setLayers({layer});

    // 设置视图范围以适应新加载的图层
    canvas->zoomToFullExtent();

}


void MainWindow::on_OpenQgzButton_clicked()
{
    // 弹出文件对话框，选择.qgz工程文件
    QString fileName = QFileDialog::getOpenFileName(this, tr("打开QGIS工程文件"), "", tr("QGIS工程文件 (*.qgz);;所有文件 (*.*)"));
    if (fileName.isEmpty()) {
        return;  // 用户取消了文件选择
    }
    // 加载QGIS工程文件 (.qgz)
    //QgsProject *project = QgsProject::instance();
    project = QgsProject::instance();

    if (!project->read(fileName)) {
        QMessageBox::warning(this, tr("加载失败"), tr("无法加载QGIS工程文件"));
        return;
    }

    // 获取项目中的所有图层
    //QList<QgsMapLayer*> Alllayers = project->mapLayers().values();
    Alllayers = project->mapLayers().values();

    if (Alllayers.isEmpty()) {
        QMessageBox::warning(this, tr("加载失败"), tr("项目中没有有效的图层"));
        return;
    }

    qDebug()<< "layerCount:" << Alllayers.count();
    canvas->setLayers(Alllayers);

    // 设置视图范围以适应所有图层
    if (!Alllayers.isEmpty()) {
        canvas->setExtent(Alllayers.first()->extent());  // 适应第一个图层的范围
    }
    // 刷新地图画布
    canvas->refresh();
    setupLayerTreeView(project);

    // 监听模型中的复选框变化并更新图层的可见性
    //connect(layerTreeModel, &QgsLayerTreeModel::dataChanged, this, &MainWindow::onLayerVisibilityChanged);
    // 调用toggleLayerVisibility函数来处理图层可见性
    //toggleLayerVisibility(layerTreeView, layerTreeModel);
    return;
}
void MainWindow::onItemClicked(QTreeWidgetItem *item, int column)
{

    qDebug() << "Item clicked: " << item->text(column)<<"  stu="<<item->checkState(column);
}


void MainWindow::onItemChanged(QTreeWidgetItem *item, int column)
{
    //qDebug() << "Item onItemChanged: " << item->text(column)<<"  stu="<<item->checkState(column);
    QString name=item->text(column);
    if (Alllayers.isEmpty()) {
        QMessageBox::warning(this, tr("加载失败onItemChanged"), tr("项目中没有有效的图层onItemChanged"));
        return;
    }
    double opt=0;
    for(QgsMapLayer *lay: Alllayers)
    {
        //qDebug() << "Item lay->name: " <<lay->name();
        if(lay->name()==name)
        {
            //opt=lay->opacity();
            //qDebug() << "Item Opacity= " <<opt;
            if(item->checkState(column)==Qt::Checked) opt=1;
            else opt=0;
            //qDebug() << "Item setOpacity: " <<name;
            lay->setOpacity(opt);
            //QgsLabelingEngine* labelingEngine = vectorLayer->labelingEngine();

            canvas->refresh();
            break;
        }
    }
}

void MainWindow::setupLayerTreeView(QgsProject *project) {

    QList<QgsMapLayer*> layers = project->mapLayers().values();
    MytreeWidget = new QTreeWidget();
    MytreeWidget->header()->hide();
    QTreeWidgetItem *item;
    qDebug()<<"setupLayerTreeView layercount="<<layers.count();
    for(QgsMapLayer *lay: layers)
    {
        qDebug()<<"setupLayerTreeView layername="<<lay->name();
        item = new QTreeWidgetItem();
        item->setText(0,lay->name());
        MytreeWidget->addTopLevelItem(item);
        item->setExpanded(true);
        item->setCheckState(0,Qt::Checked);
    }
    // 连接信号和槽
    //connect(MytreeWidget, &QTreeWidget::itemClicked, this, &MainWindow::onItemClicked);
    connect(MytreeWidget, &QTreeWidget::itemChanged, this, &MainWindow::onItemChanged);
    // 创建一个QSplitter，水平布局
    QSplitter *splitter = new QSplitter(Qt::Horizontal);
    // 将layerTreeView添加到splitter中
    splitter->addWidget(MytreeWidget);
    splitter->addWidget(canvas);  // 你可以将canvas或其他控件添加到splitter中
    // 将splitter添加到布局中
    ui->horizontalLayout02->addWidget(splitter);
    // 可选：设置默认宽度比例
    splitter->setSizes(QList<int>() << 200 << 600);  // 这里设置了layerTreeView和canvas的初始宽度比例
    return;
}

void MainWindow::AddLayerTreeView(QgsRasterLayer* newlayer)
{

    qDebug()<<"AddLayerTreeView layername="<<newlayer->name();
    QTreeWidgetItem *item;
    item = new QTreeWidgetItem();
    item->setText(0,newlayer->name());
    qDebug()<<"AddLayerTreeView 00000000001="<<MytreeWidget;
    MytreeWidget->addTopLevelItem(item);
    qDebug()<<"AddLayerTreeView 11111111111="<<newlayer->name();
    item->setExpanded(true);
    item->setCheckState(0,Qt::Checked);

    return;
}
/*
void MainWindow::setupLayerTreeView(QgsProject *project) {
    // 创建QgsLayerTreeView来显示图层树
    QgsLayerTreeView *layerTreeView = new QgsLayerTreeView();
    // 创建图层树模型
    QgsLayerTreeModel *layerTreeModel = new QgsLayerTreeModel(project->layerTreeRoot());
    // 设置模型
    layerTreeView->setModel(layerTreeModel);
    // 创建复选框委托
    LayerCheckBoxDelegate *checkBoxDelegate = new LayerCheckBoxDelegate(layerTreeView);
    layerTreeView->setItemDelegate(checkBoxDelegate);
    // 创建一个QSplitter，水平布局
    QSplitter *splitter = new QSplitter(Qt::Horizontal);
    // 将layerTreeView添加到splitter中
    splitter->addWidget(layerTreeView);
    splitter->addWidget(canvas);  // 你可以将canvas或其他控件添加到splitter中
    // 将splitter添加到布局中
    ui->horizontalLayout02->addWidget(splitter);
    // 可选：设置默认宽度比例
    splitter->setSizes(QList<int>() << 200 << 600);  // 这里设置了layerTreeView和canvas的初始宽度比例
    return;
}
*/
/*
//void MainWindow::setupLayerTreeView(QgsProject *project, QWidget *parent) {
void MainWindow::setupLayerTreeView(QgsProject *project, QHBoxLayout *parent) {
    // 创建QgsLayerTreeView
    //QgsLayerTreeView *layerTreeView = new QgsLayerTreeView(parent);
    QgsLayerTreeView *layerTreeView = new QgsLayerTreeView();
    // 创建图层树模型
    QgsLayerTreeModel *layerTreeModel = new QgsLayerTreeModel(project->layerTreeRoot());
    // 设置模型
    layerTreeView->setModel(layerTreeModel);

    // 创建复选框委托
    LayerCheckBoxDelegate *checkBoxDelegate = new LayerCheckBoxDelegate(layerTreeView);
    layerTreeView->setItemDelegate(checkBoxDelegate);

    // 创建一个QSplitter，水平布局
    QSplitter *splitter = new QSplitter(Qt::Horizontal, parent);
    splitter->addWidget(layerTreeView);
    // 可以将canvas或其他控件添加到splitter中
    splitter->setStretchFactor(1, 1);

    // 将splitter添加到布局中
    QVBoxLayout *layout = new QVBoxLayout(parent);
    layout->addWidget(splitter);
    parent->setLayout(layout);
}
*/

/*
// 函数：处理图层可见性的切换
void MainWindow::toggleLayerVisibility(QgsLayerTreeView *layerTreeView, QgsLayerTreeModel *layerTreeModel)
{
    // 监听图层树视图的选择变化
    QObject::connect(layerTreeView->selectionModel(), &QItemSelectionModel::selectionChanged,
                     [layerTreeModel](const QItemSelection &selected, const QItemSelection &deselected)
    {
                                 // 处理选中的图层
                         QModelIndexList selectedIndexes = selected.indexes();
                         for (const QModelIndex &index : selectedIndexes) {
                             qDebug()<<"11111111111selectedIndexes"<<index.row()<<","<<index.column();
                             QgsLayerTreeNode *node = layerTreeModel->index2node(index.child(1,0));
                             if (node) {
                                 // 遍历当前节点的所有子节点
                                 for (int i = 0; i < node->children().count(); ++i) {
                                     QgsLayerTreeNode* childNode = node->children().at(i);
                                     // 如果子节点是图层节点
                                     if (QgsLayerTreeLayer* layerNode = dynamic_cast<QgsLayerTreeLayer*>(childNode)) {
                                         QgsMapLayer* layer = layerNode->layer();
                                         if (layer) {
                                             layerNode->setItemVisibilityChecked(true);
                                         }
                                     }
                                 }
                             }
                         }
                         // 处理取消选中的图层
                         QModelIndexList deselectedIndexes = deselected.indexes();
                         for (const QModelIndex &index : deselectedIndexes) {
                             qDebug()<<"22222222222deselectedIndexes"<<index.row()<<","<<index.column();
                             // 获取取消选中的图层节点
                             QgsLayerTreeNode *node = layerTreeModel->index2node(index.child(1,0));
                             if (node) {
                                 for (int i = 0; i < node->children().count(); ++i) {
                                     QgsLayerTreeNode* childNode = node->children().at(i);
                                     // 如果子节点是图层节点
                                     if (QgsLayerTreeLayer* layerNode = dynamic_cast<QgsLayerTreeLayer*>(childNode)) {
                                         QgsMapLayer* layer = layerNode->layer();
                                         if (layer) {
                                             // 设置图层可见性为false
                                             layerNode->setItemVisibilityChecked(false);
                                         }
                                     }
                                 }
                             }
                         }
                         //qDebug()<<"3333333333333333333";
    });
}
*/

void MainWindow::onLayerVisibilityChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
{

    // 确保我们只处理复选框的状态变化
    qDebug()<< "onLayerVisibilityChanged:" << topLeft.column();
    if (topLeft.column() == 0) {
        // 获取节点对应的图层树节点
        QgsLayerTreeNode *node = static_cast<QgsLayerTreeNode*>(topLeft.internalPointer());
        if (node) {
            // 检查该节点是否是一个 QgsLayerTreeLayer 节点
            QgsLayerTreeLayer *layerNode = dynamic_cast<QgsLayerTreeLayer*>(node);
            if (layerNode) {
                QgsMapLayer *layer = layerNode->layer();  // 获取关联的图层
                if (layer) {
                    bool isChecked = topLeft.model()->data(topLeft, Qt::CheckStateRole).toBool();
                    // 通过图层树节点来控制图层的可见性
                    layerNode->setItemVisibilityChecked(isChecked);  // 使用 setItemVisibilityChecked
                    canvas->refresh();  // 刷新地图显示
                }
            }
        }
    }
}
// void MainWindow::on_openMbtButton_clicked()
// {
//     // 弹出文件对话框，选择.mbtiles文件
//     QString fileName = QFileDialog::getOpenFileName(this, tr("打开MBTiles文件"), "", tr("MBTiles (*.mbtiles);;所有文件 (*.*)"));
//     if (fileName.isEmpty()) {
//         return;  // 用户取消了文件选择
//     }

//     // 加载MBTiles文件
//     QgsRasterLayer *layer = new QgsRasterLayer(fileName, "MBTiles Layer");

//     // 检查图层是否有效
//     if (!layer->isValid()) {
//         QMessageBox::warning(this, tr("加载失败"), tr("无法加载MBTiles文件"));
//         delete layer;
//         return;
//     }

//     // 将图层添加到QGIS项目中
//     QgsProject::instance()->addMapLayer(layer);

//     // 将图层显示在地图画布上
//     canvas->setLayers({layer});

//     // 设置视图范围以适应新加载的图层
//     canvas->zoomToFullExtent();
// }


void MainWindow::on_AddMbtButton_clicked()
{
    // 弹出文件对话框，选择.mbtiles文件
    QString fileName = QFileDialog::getOpenFileName(this, tr("添加MBTiles文件"), "", tr("MBTiles (*.mbtiles);;所有文件 (*.*)"));
    if (fileName.isEmpty()) {
        return;  // 用户取消了文件选择
    }

    // 加载MBTiles文件
    QgsRasterLayer *newLayer = new QgsRasterLayer(fileName, "MBTiles Layer");

    // 检查图层是否有效
    if (!newLayer->isValid()) {
        QMessageBox::warning(this, tr("加载失败"), tr("无法加载MBTiles文件"));
        delete newLayer;
        return;
    }

    // 将新图层添加到 QGIS 项目中
    QgsProject::instance()->addMapLayer(newLayer);

    // 获取现有图层，并将其与新图层一起显示在地图画布上
    //QList<QgsMapLayer *> layers = QgsProject::instance()->mapLayers().values();
    Alllayers = QgsProject::instance()->mapLayers().values();

    // 将图层显示在地图画布上
    //canvas->setLayers({layers});
    canvas->setLayers(Alllayers);

    // 设置视图范围以适应新加载的图层
    //canvas->zoomToFullExtent();
    //setupLayerTreeView(project);
    AddLayerTreeView(newLayer);
}



void MainWindow::DrawPoints(QList<QgsPoint> Pointlist)
{
    int i,cnt;
    // 1. 创建一个新的矢量图层（点图层）
    QgsVectorLayer* pointLayer = new QgsVectorLayer("Point?crs=EPSG:4326", "DrawPoints", "memory");
    if (!pointLayer->isValid()) {
        QMessageBox::warning(this, tr("加载失败"), tr("无法创建点图层"));
        delete pointLayer;
        return;
    }

    // 2. 设置图层的字段（例如，添加一个 ID 字段）
    QgsFields fields;
    fields.append(QgsField("ID", QVariant::Int)); // 添加一个 ID 字段
    //fields.append(QgsField("name", QVariant::String)); // 添加一个 ID 字段
    //fields.append(QgsField("age", QVariant::Int)); // 添加一个 ID 字段
    pointLayer->dataProvider()->addAttributes(fields.toList());
    pointLayer->updateFields();  // 更新字段

    QgsFeature pointFeature;
    pointFeature.setFields(fields);  // 显式地设置字段集合
    cnt=Pointlist.count();
    qDebug()<<"2PointList Count:"<<Pointlist.count();
    for(i=0;i<cnt;i++)
    {
        pointFeature.setGeometry(QgsGeometry::fromPointXY(Pointlist[i]));
        pointFeature.setAttributes(QgsAttributes({QVariant(i)}));  // 设置 ID 为 i
        pointLayer->dataProvider()->addFeature(pointFeature);
    }

    // 5. 更新图层的范围
    pointLayer->updateExtents();  // 确保图层的范围更新

    // 6. 设置点的样式
    QgsMarkerSymbol *defSymbol = QgsMarkerSymbol::createSimple({{"name", "circle"}, {"color", "red"}, {"size", "0"}});
    // 设置圆形符号，设置大小和颜色
    QgsMarkerSymbol *circleSymbol = QgsMarkerSymbol::createSimple({{"name", "circle"}, {"color", "red"}, {"size", "6"}});
    // 设置五角星形符号，设置大小和颜色
    QgsMarkerSymbol *starSymbol = QgsMarkerSymbol::createSimple({{"name", "star"}, {"color", "blue"}, {"size", "5"}});
    // 设置五角星形符号，设置大小和颜色
    QgsMarkerSymbol *triangleSymbol = QgsMarkerSymbol::createSimple({{"name", "triangle"}, {"color", "yellow"}, {"size", "3"}});
    // 使用规则渲染器（QgsRuleBasedRenderer）

    //注意：是在缺省符号基础上绘制规则匹配符号，而不是只绘制匹配符号
    //QgsRuleBasedRenderer *renderer = new QgsRuleBasedRenderer(circleSymbol);// 默认符号是五角星形符号
    QgsRuleBasedRenderer *renderer = new QgsRuleBasedRenderer(defSymbol);// 默认符号是五角星形符号


    // 第一个规则：ID = 1 的点使用圆形符号
    QgsRuleBasedRenderer::Rule* rule1 = new QgsRuleBasedRenderer::Rule(circleSymbol);
    rule1->setLabel("Circle");
    rule1->setFilterExpression("ID%3 = 0");  // 用 ID 过滤条件为 1 的点使用圆形符号
    renderer->rootRule()->appendChild(rule1);

    // 第二个规则：ID = 2 的点使用五角星符号
    QgsRuleBasedRenderer::Rule* rule2 = new QgsRuleBasedRenderer::Rule(starSymbol);
    rule2->setLabel("Star");
    rule2->setFilterExpression("ID%3 = 1");  // 用 ID 过滤条件为 2 的点使用五角星符号
    renderer->rootRule()->appendChild(rule2);

    // 第二个规则：ID = 3 的点使用五角星符号
    QgsRuleBasedRenderer::Rule* rule3 = new QgsRuleBasedRenderer::Rule(triangleSymbol);
    rule3->setLabel("Triangle");
    rule3->setFilterExpression("ID%3 = 2");  // 用 ID 过滤条件为 2 的点使用五角星符号
    renderer->rootRule()->appendChild(rule3);

    // 设置点图层的渲染器
    pointLayer->setRenderer(renderer);

    // 7. 刷新图层
    pointLayer->triggerRepaint();

    // 8. 将新图层添加到项目中
    QgsProject::instance()->addMapLayer(pointLayer);

    // 9. 更新地图画布，确保图层显示
    //canvas->setLayers(QgsProject::instance()->mapLayers().values()); // 更新画布上的图层

    DispPointLabelById(pointLayer, 1, "DrawPL-第2个点的标签");
    DispPointLabelById(pointLayer, 3, "DrawPL-第4个点的标签");
    DispPointLabelById(pointLayer, 4, "DrawPL-第5个点的标签");
    enableLabeling(pointLayer);  // 启用标签显示
    movePointById(pointLayer, 1, -0.5, -0.5);

    PrintVectorLayerData(pointLayer);
    return;
}
void MainWindow::DrawLines(QList<QgsPoint> Pointlist)
{
    int i,j,cnt=8,lcnt=8;
    // 1. 创建一个新的矢量图层（点图层）
    QgsVectorLayer* lineLayer = new QgsVectorLayer("LineString?crs=EPSG:4326", "DrawLines", "memory");
    if (!lineLayer->isValid()) {
        QMessageBox::warning(this, tr("加载失败"), tr("无法创建线图层"));
        delete lineLayer;
        return;
    }

    // 2. 设置图层的字段（例如，添加一个 ID 字段）
    QgsFields fields;
    fields.append(QgsField("ID", QVariant::Int)); // 添加一个 ID 字段
    //fields.append(QgsField("name", QVariant::String)); // 添加一个 ID 字段
    //fields.append(QgsField("age", QVariant::Int)); // 添加一个 ID 字段
    lineLayer->dataProvider()->addAttributes(fields.toList());
    lineLayer->updateFields();  // 更新字段

    DrawLine(lineLayer,fields,Pointlist,0);
    cnt=Pointlist.count();
    for(j=1;j<lcnt;j++)
    {
        for(i=0;i<cnt;i++)
        {
            double yy=Pointlist[i].y();
            Pointlist[i].setY(yy+0.2);
        }
        DrawLine(lineLayer,fields,Pointlist,j);
    }
    // // 6. 设置线的样式
    QgsLineSymbol *defLineSymbol = QgsLineSymbol::createSimple({{"line_style", "dot"},{"color", "red"}, {"width", "0.01"}});
    QgsLineSymbol *dotLineSymbol = QgsLineSymbol::createSimple({{"line_style", "dot"},{"color", "red"}, {"width", "0.6"}});
    QgsLineSymbol *dashLineSymbol = QgsLineSymbol::createSimple({{"line_style", "dash"},{"color", "blue"}, {"width", "0.4"}});
    //"solid"：实线（默认值）。"dash"：虚线（短划线）。 "dot"：点线。 "dash_dot"：短划线和点的组合线。
    QgsLineSymbol *solidLineSymbol = QgsLineSymbol::createSimple({{"line_style", "solid"},{"color", "yellow"}, {"width", "0.2"}});
    QgsRuleBasedRenderer *renderer = new QgsRuleBasedRenderer(defLineSymbol);// 默认符号

    // 第一个规则：ID = 1 的点使用点线符号
    QgsRuleBasedRenderer::Rule* rule1 = new QgsRuleBasedRenderer::Rule(dotLineSymbol);
    rule1->setLabel("Dot");
    rule1->setFilterExpression("ID%3 = 0");  // 用 ID 过滤条件为 1 的点使用圆形符号
    renderer->rootRule()->appendChild(rule1);

    // 第二个规则：ID = 2 的点使用虚线符号
    QgsRuleBasedRenderer::Rule* rule2 = new QgsRuleBasedRenderer::Rule(dashLineSymbol);
    rule2->setLabel("dash");
    rule2->setFilterExpression("ID%3 = 1");  // 用 ID 过滤条件为 2 的点使用五角星符号
    renderer->rootRule()->appendChild(rule2);

    // 第二个规则：ID = 3 的点使用实线符号
    QgsRuleBasedRenderer::Rule* rule3 = new QgsRuleBasedRenderer::Rule(solidLineSymbol);
    rule3->setLabel("solid");
    rule3->setFilterExpression("ID%3 = 2");  // 用 ID 过滤条件为 2 的点使用五角星符号
    renderer->rootRule()->appendChild(rule3);

    // 设置点图层的渲染器
    lineLayer->setRenderer(renderer);

    // 7. 刷新图层
    lineLayer->triggerRepaint();

    // 8. 将新图层添加到项目中
    QgsProject::instance()->addMapLayer(lineLayer);


    PrintVectorLayerData(lineLayer);

    // 9. 更新地图画布，确保图层显示
    //canvas->setLayers(QgsProject::instance()->mapLayers().values()); // 更新画布上的图层
    return;
}

void MainWindow::DrawLine(QgsVectorLayer* lineLayer,QgsFields fields,QList<QgsPoint> Pointlist,int i)
{

    // 遍历 QList<QgsPoint> 并转换为 QVector<QgsPointXY>
    QVector<QgsPointXY> points;
    for (const QgsPoint& point : Pointlist) {
        QgsPointXY pointXY(point.x(), point.y());  // 创建 QgsPointXY
        points.append(pointXY);  // 添加到 QVector 中
    }
    QgsFeature lineFeature;
    lineFeature.setFields(fields);  // 显式地设置字段集合
    // 3. 创建线段
    // 创建 QgsPolylineXY 对象
    QgsPolylineXY line (points);
    lineFeature.setGeometry(QgsGeometry::fromPolylineXY(line));
    //lineFeature.setAttributes({i});  // 设置 ID 为 i
    lineFeature.setAttributes(QgsAttributes({QVariant(i)}));  // 设置 ID 为 i
    lineLayer->dataProvider()->addFeature(lineFeature);
    // 5. 更新图层的范围
    lineLayer->updateExtents();  // 确保图层的范围更新
    return;
}
void MainWindow::PrintVectorLayerData(QgsVectorLayer* VecLayer)
{
    // 获取图层中的所有要素
    QgsFeatureIterator featureIterator = VecLayer->getFeatures();
    // 遍历所有要素
    QgsFeature feature;
    while (featureIterator.nextFeature(feature)) {
        // 获取当前要素的几何体
        QgsGeometry geom = feature.geometry();
        // 确保几何体是点类型
        if (geom.type() == Qgis::GeometryType::Point) {
            // 获取点的坐标
            QgsPointXY point = geom.asPoint();
            // 获取点的属性（例如，ID）
            int pointID = feature.attribute("ID").toInt();
            // 输出点的坐标和属性（ID）
            qDebug() << "Point ID: " << pointID << ", Coordinates: (" << point.x() << ", " << point.y() << ")";
        }
        if (geom.type() == Qgis::GeometryType::Line) {
            // 获取点的坐标
            //QgsMultiPointXY multiPoint = geom.asMultiPoint();
            QgsPolylineXY  points = geom.asPolyline();  // 获取线几何对象

            // 获取点的属性（例如，ID）
            int pointID = feature.attribute("ID").toInt();
            // 输出点的坐标和属性（ID）
            //qDebug() << "Line ID: " << pointID << ", Coordinates[0]: (" << point.value(0).x() << ", " << point.value(0).y() << ")";
            // 遍历 QgsMultiPointXY 中的所有 QgsPointXY 点并打印坐标
            qDebug() << "Line ID: " << pointID << ",PointCount:"<<points.count()<<" points[0]="<<points[0].x()<<points[0].y();
            // // 获取并打印线中的每个点的坐标
            // for (const QgsPointXY& point : points) {
            //     qDebug() << "Point:" << point.x() << point.y();
            // }
        }
    }
    return;
}
void MainWindow::on_DrawPLButton_clicked()
{
    int i,cnt=8;
    QList<QgsPoint> Pointlist;
    QgsPoint onepnt(115.0, 40.0);
    Pointlist.append(onepnt);
    for(i=1;i<cnt;i++)
    {
        double xx=onepnt.x();
        onepnt.setX(xx+0.5);
        Pointlist.append(onepnt);
    }
    qDebug()<<"PointList Count:"<<Pointlist.count();
    DrawPoints(Pointlist);
    DrawLines(Pointlist);
    // 9. 更新地图画布，确保图层显示
    canvas->setLayers(QgsProject::instance()->mapLayers().values()); // 更新画布上的图层
    return;
}
void MainWindow::movePointById(QgsVectorLayer* pointLayer, int pointId, double offsetX, double offsetY)
{
    // 启用编辑模式
    if (!pointLayer->isEditable()) {
        pointLayer->startEditing();
        qDebug()<<"Set pointLayer->isEditable";
    }

    // 创建一个请求，查找ID匹配的要素
    QgsFeatureRequest request;
    request.setFilterExpression(QString("ID = %1").arg(pointId));

    // 遍历图层中的要素，找到ID匹配的点
    QgsFeature feature;
    QgsFeatureIterator iter = pointLayer->getFeatures(request);
    while (iter.nextFeature(feature)) {
        // 获取当前要素的几何体
        QgsGeometry geometry = feature.geometry();

        if (!geometry.isEmpty() && geometry.type() == Qgis::GeometryType::Point) {
            // 获取当前点的坐标
            QgsPointXY point = geometry.asPoint();

            // 计算新的位置
            QgsPointXY newPoint(point.x() + offsetX, point.y() + offsetY);

            // 创建一个新的几何体
            QgsGeometry newGeometry = QgsGeometry::fromPointXY(newPoint);

            // 更新要素的几何体
            feature.setGeometry(newGeometry);

            // 更新图层中的要素
            pointLayer->updateFeature(feature);
            break;  // 只移动第一个匹配的点
        }
    }

    // 提交编辑
    //pointLayer->commitChanges();
}
void MainWindow::DispPointLabelById(QgsVectorLayer* pointLayer, int pointId, QString label)
{
    // 启用编辑模式
    if (!pointLayer->isEditable()) {
        pointLayer->startEditing();
        qDebug()<<"DispPointLabelById()Set_pointLayer->isEditable";
    }

    // 添加标签字段（如果不存在的话）
    QgsFields fields = pointLayer->fields();
    // 检查是否已有"label"字段，如果没有则添加
    if (fields.indexOf("label") == -1) {
        QgsField labelField("label", QVariant::String);
        pointLayer->dataProvider()->addAttributes({ labelField });
        pointLayer->updateFields();
    }

    // 创建一个请求，查找ID匹配的要素
    QgsFeatureRequest request;
    request.setFilterExpression(QString("ID = %1").arg(pointId));

    QgsFeature feature;
    QgsFeatureIterator iter = pointLayer->getFeatures(request);
    while (iter.nextFeature(feature)) {
        // 设置该要素的标签字段值
        feature.setAttribute("label", label);  // 设置"label"字段的值

        // 更新要素
        pointLayer->updateFeature(feature);
        break;  // 假设ID是唯一的，只修改第一个匹配的点
    }

    // 提交编辑
    pointLayer->commitChanges();

    // 重新渲染图层，更新标签
    pointLayer->triggerRepaint();
 }
void MainWindow::enableLabeling(QgsVectorLayer* pointLayer)
{
    // 创建 QgsTextFormat 对象
    QgsTextFormat textFormat;
    textFormat.setFont(QFont("Arial", 10));  // 设置字体和大小
    textFormat.setColor(Qt::yellow);  // 设置字体颜色
    QgsPalLayerSettings labelSettings;
    labelSettings.setFormat(textFormat);
    labelSettings.fieldName = "label";  // 直接赋值给 fieldName
    QgsVectorLayerSimpleLabeling* labeling = new QgsVectorLayerSimpleLabeling(labelSettings);
    // 启用标签
    pointLayer->setLabelsEnabled(true);  // 启用标签显示
    pointLayer->setLabeling(labeling);  // 设置标签渲染引擎
    // 更新标签设置
    pointLayer->triggerRepaint();
}

